package com.itheima.app.manager;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.itheima.autoconfig.face.AipFaceTemplate;
import com.itheima.autoconfig.huanxin.HuanXinTemplate;
import com.itheima.autoconfig.oss.OssTemplate;
import com.itheima.autoconfig.sms.SmsTemplate;
import com.itheima.domain.db.Log;
import com.itheima.domain.db.User;
import com.itheima.domain.db.UserInfo;
import com.itheima.vo.UserInfoVo;
import com.itheima.service.db.UserInfoService;
import com.itheima.service.db.UserService;
import com.itheima.util.ConstantUtil;
import com.itheima.util.JwtUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service //spring的
public class
UserManager {

    @Reference //调用远程的service服务提供者
    private UserService userService;
    @Reference
    private UserInfoService userInfoService;

    @Autowired
    private SmsTemplate smsTemplate;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private AipFaceTemplate aipFaceTemplate;
    @Autowired
    private OssTemplate ossTemplate;
    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    //保存用户
    public Long save(User user) {

        //保存密码(加密)
        user.setPassword(SecureUtil.md5(user.getPassword()));

        //调用service保存
        Long id = userService.save(user);


        //需求：返回主键
        return id;
    }

    //根据手机号查询用户
    public User findByPhone(String phone) {

        //调用service按手机号查询用户
        User user = userService.findByPhone(phone);

        //返回查询用户信息
        return user;
    }

    //发送验证码
    public void sendSmsCode(String phone) {
        User us = userService.findByPhone(phone);
        //查询用户被封.了没有
        if (stringRedisTemplate.hasKey(us.getId()+"loginState")){
            //有 说明封了
            System.out.println("  ");
            throw new RuntimeException("" ) ;
        }




        //1.生成验证码
        // String code = RandomUtil.randomNumbers(6);
        String code ="123456";//佟倩验证码123456

        //2.发送验证码(没钱了，所以不发了)
        //smsTemplate.sendSms(phone,code);
        System.out.println(code);

        //3.保存验证码到redis
        stringRedisTemplate.opsForValue().set(ConstantUtil.SMS_CODE + phone, code, Duration.ofMinutes(5));
    }

    //登录或注册
    public Map<String, Object> loginOrReg(String phone, String verificationCode) {
        //验证码
        String codeFromRedis = stringRedisTemplate.opsForValue().get(ConstantUtil.SMS_CODE + phone);
        if (!StringUtils.equals(codeFromRedis, verificationCode)) {
            //比对失败
            throw new RuntimeException("验证码错误");
        }

        //比对成功
        stringRedisTemplate.delete(ConstantUtil.SMS_CODE + phone);//比对成功，删除验证码

        //查询手机号
        User user = userService.findByPhone(phone);

        boolean isNew;
        /*String type = "0101";//登录*/

        if (user != null) {
            Long id = user.getId();
            //接收一下冻结原因
            String freezeReason = null;
            //获取冻结原因
            if(stringRedisTemplate.hasKey("freezeReason")){
                freezeReason = stringRedisTemplate.opsForValue().get("freezeReason");
            }
            //如果redis有这个key，不允许登录
            if(stringRedisTemplate.hasKey(id+"loginState")){
                throw new RuntimeException("您的账号因"+freezeReason+"已冻结，请大喊一声勇敢牛牛，不怕困难！");
            }
            //用户存在=>走登录
            isNew = false;
        } else {
            //用户不存在=>注册
            user = new User();
            user.setPhone(phone);
            user.setPassword(SecureUtil.md5(ConstantUtil.INIT_PASSWORD));
            Long userId = userService.save(user);
            user.setId(userId);

            //向环信发送注册用户
            huanXinTemplate.register(user.getId());

            //新用户
            isNew = true;

           /* type = "0102"; //登录*/
        }

        /*Log log = new Log();
        log.setType(type);//操作类型
        log.setUserId(user.getId());//用户id
        log.setLogTime(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));//操作日期
        log.setPlace("北京顺义");//mongo中的location中有,下课自己完成
        log.setEquipment("华为19");//设备名称
        rocketMQTemplate.convertAndSend("tanhua-log", log);*/

        //创建token
        HashMap<String, Object> tokenMap = new HashMap<>();
        tokenMap.put("id", user.getId());
        tokenMap.put("phone", user.getPhone());
        String token = JwtUtil.createToken(tokenMap);
        //将token保存到redis                                                       //value是什么不重要，到时候只看有没有这个key==>token
        stringRedisTemplate.opsForValue().set(ConstantUtil.USER_TOKEN + token, "1", Duration.ofDays(30));


        //把token的有效时间设置为2小时
        //方案一: 每次客户端访问服务器的时候,服务器要进行token续期(重新颁发token,或者修改时间), 还要将修改之后的token再返回去,这时候前端需要提供一个接受token的接口
        //方案二: 用户登录成功之后,要将当前token存入redis(设置有效期), 每次客户端访问服务器的时候,我们还需要校验redis中是否还有这个token,如果有的话,将时长续期


        //5. 返回结果map
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("token", token);
        resultMap.put("isNew", isNew);

        return resultMap;
    }


    //完善个人信息
    public void saveUserBaseInfo(UserInfo userInfo) {
        userInfoService.save(userInfo);
    }

    //完善个人头像信息
    public void saveUserHeaderInfo(Long userId, MultipartFile headPhoto) throws IOException {

        //1.先人脸检查
        boolean detect = aipFaceTemplate.detect(headPhoto.getBytes());
        System.out.println("=================>人脸识别的结果：" + detect);

        if (!detect) {
            //人脸识别失败
            throw  new RuntimeException("人脸识别失败");
        }


        //人脸识别成功==>2.再进行头像上传
        String filePath = ossTemplate.upload(headPhoto.getOriginalFilename(), headPhoto.getInputStream());
        System.out.println("=================>头像的路径：" + filePath);

        //3.更新mysql数据库中的头像地址==>update avatar=?,coverPic=? where id = ?
        UserInfo userInfo = new UserInfo();
        userInfo.setAvatar(filePath);
        userInfo.setCoverPic(filePath);
        userInfo.setId(userId);


        userInfoService.update(userInfo);
    }

    //根据userId查询用户信息
    public UserInfoVo findUserById(Long userId) {

        UserInfo userInfo = userInfoService.findByUserId(userId);

        //给userInfoVo赋值
        UserInfoVo userInfoVo = new UserInfoVo();
        //赋值属性，前提成员属性的名称，类型完全一致，不一致的不赋值
        BeanUtil.copyProperties(userInfo,userInfoVo);
        //UserInfo的age是Integer，UserInfoVo的age是String，要转换下类型再存入
        userInfoVo.setAge(userInfo.getAge()+"z");
        return userInfoVo;
    }

    //更新个人基本信息
    public void updateUserBaseInfo(UserInfo userInfo) {
        userInfoService.update(userInfo);
    }
}
